剑指 Offer 04. 二维数组中的查找

在一个 n * m 的二维数组中,每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。

示例:

现有矩阵 matrix 如下:

[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true

给定 target = 20,返回 false

限制:

0 <= n <= 1000

0 <= m <= 1000

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof


二分查找

看到有序想到了【二分查找】,所以可以使用横向二分查找与纵向二分查找解决此题

如果横向和纵向均为找到 target 则返回 false

class Solution:
    def findNumberIn2DArray(self, matrix: List[List[int]], target: int) -> bool:
        if not matrix:
            return False
        length = len(matrix[0])

        # 横向二分查找
        for nums in matrix:
            result = self.bisect(nums, target)
            if result:
                return True
        
        # 将数组转置
        new_matrix = list(zip(*matrix))

        for nums in new_matrix:
            result = self.bisect(nums, target)
            if result:
                return True

        return False

    def bisect(self, nums, target) -> bool:
        size = len(nums)
        left, right = 0, size - 1
        while left <= right:
            mid = (left + right) >> 1

            if nums[mid] == target:
                return True
            elif nums[mid] < target:
                left = mid + 1
            else:
                right = mid - 1
        return False

线性查找

在上一方法中,并未完全利用 每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序 这一条件

参考题解:
面试题04. 二维数组中的查找

二维数组原来这么好玩,题解剑指 offer 第 4 号算法题:搜索二维矩阵

从二维数组的右上角开始查找。
如果当前元素等于目标值,则返回 true。
如果当前元素大于目标值,则移到左边一列。
如果当前元素小于目标值,则移到下边一行。

class Solution:
    def findNumberIn2DArray(self, matrix, target) -> bool:
        # 针对[]和[[]]这种特殊情况
        if len(matrix)==0 or len(matrix[0])==0:
            return False
        
        # 矩阵尺寸
        height = len(matrix)
        width = len(matrix[0])

        # 右上角开始检索
        row=0
        col=width-1

        while row<height and col>=0:
            # print("Row:{},Col:{}".format(row,col))
            if matrix[row][col] > target:
                col = col-1
            elif matrix[row][col] < target:
                row = row+1
            elif matrix[row][col] == target:
                return True
        return False